package com.li.hello.commons.utils;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.util.*;

/**
 * Xml格式转换工具类
 */
public class XmlUtils {

    /**
     * 将xml转为对象
     *
     * @param clazz
     * @param context
     * @return
     * @throws JAXBException
     */
    @SuppressWarnings("unchecked")
    public static <T> T readString(Class<T> clazz, String context) throws JAXBException {
        try {
            JAXBContext jc = JAXBContext.newInstance(clazz);
            Unmarshaller u = jc.createUnmarshaller();
            return (T) u.unmarshal(new StringReader(context));
        } catch (JAXBException e) {
            throw e;
        }
    }

    /**
     * xml 转换为List<Map<String,Object>>
     *
     * @param xml
     * @param nodeName
     * @return
     * @throws Exception
     */
    public static List<Map<String, Object>> readXmlList(String xml, String nodeName) throws Exception {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Document document = DocumentHelper.parseText(xml);
        Element nodesElement = listNodes(document.getRootElement(), nodeName);
        if (null != nodesElement) {
            List nodes = nodesElement.elements();
            for (Iterator its = nodes.iterator(); its.hasNext(); ) {
                Element nodeElement = (Element) its.next();
                Map<String, Object> map = xmltoMap(nodeElement.asXML(), nodeElement.getName());
                list.add(map);
            }
        }
        return list;
    }


    /**
     * 迭代获取节点
     *
     * @param node
     * @param nodeName
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Element listNodes(Element node, String nodeName) {
        Element res = null;
        if (nodeName.equals(node.getName())) {
            return node;
        } else {
            // 当前节点下面子节点迭代器
            Iterator<Element> it = node.elementIterator();
            // 遍历
            while (it.hasNext()) {
                // 获取某个子节点对象
                Element e = it.next();
                // 对子节点进行遍历
                res = listNodes(e, nodeName);
                if (res != null) {
                    break;
                }
            }
            return res;
        }
    }


    /**
     * xml转化为map
     *
     * @param xml
     * @param nodeName
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    private static Map<String, Object> xmltoMap(String xml, String nodeName) {
        try {
            Map<String, Object> map = new HashMap();
            Document document = DocumentHelper.parseText(xml);
            Element nodeElement = listNodes(document.getRootElement(), nodeName);
            if (null != nodeElement) {
                List node = nodeElement.elements();
                for (Iterator it = node.iterator(); it.hasNext(); ) {
                    Element elm = (Element) it.next();
                    List nodes = elm.elements();
                    if (nodes.isEmpty()) {
                        map.put(elm.getName(), elm.getText());
                    } else {
                        Map<String, Object> maps = new HashMap();
                        map.put(elm.getName(), maps);
                    }
                }
            }
            return map;
        } catch (Exception e) {
//            logger.error(e.getMessage());
        }
        return null;
    }
}
